From 1dca4dde9687bd214691b987cdffd87f389e07b6 Mon Sep 17 00:00:00 2001 From: jdd272 Date: Thu, 21 Nov 2024 15:52:54 +0100 Subject: [PATCH] luci-app-statistics: support VPN client and VPN server(multi-users) Keep displaying Compression/Trafic graphs for OpenVPN clients, but also support status-version 2 OpenVPN server instance. If multi mode is enabled it displays one graph (Traffic) per connected user. Added another graph to display total number of connected users if the option is enabled in collectd. Signed-off-by: Julien DIOUF --- .../statistics/rrdtool/definitions/openvpn.js | 72 +++++++++++++++++-- 1 file changed, 66 insertions(+), 6 deletions(-) diff --git a/applications/luci-app-statistics/htdocs/luci-static/resources/statistics/rrdtool/definitions/openvpn.js b/applications/luci-app-statistics/htdocs/luci-static/resources/statistics/rrdtool/definitions/openvpn.js index f78e2a491c..fea570f8d3 100644 --- a/applications/luci-app-statistics/htdocs/luci-static/resources/statistics/rrdtool/definitions/openvpn.js +++ b/applications/luci-app-statistics/htdocs/luci-static/resources/statistics/rrdtool/definitions/openvpn.js @@ -8,9 +8,20 @@ return baseclass.extend({ rrdargs: function(graph, host, plugin, plugin_instance, dtype) { var inst = plugin_instance.replace(/^openvpn\.(.+)\.status$/, '$1'); + const types = graph.dataTypes(host, plugin, plugin_instance); + const rv = []; + let instances; + const typeinstances = graph.dataInstances(host, plugin, plugin_instance, "if_octets").sort(); - return [ - { + function find_instances(dtype, wanted) { + const matching = graph.dataInstances(host, plugin, plugin_instance, dtype).filter(function(instance) { + return wanted.indexOf(instance) > -1; + }); + return matching.length ? { [dtype]: matching } : null; + } + + if ((instances = find_instances('if_octets', ['overhead', 'traffic'])) !== null) { + rv.push({ title: "%%H: OpenVPN \"%s\" - Traffic".format(inst), vlabel: "Bytes/s", data: { @@ -27,9 +38,57 @@ return baseclass.extend({ if_octets_traffic_rx : { weight: 3, title: "Bytes (RX)", total: true, flip: true, color: "0000ff" } } } - }, + }); + } else { + for (const tinstance of typeinstances) { + const rx = "if_octets_%s_rx".format(tinstance); + const tx = "if_octets_%s_tx".format(tinstance); + const opts = {}; + opts[tx] = { weight: 0, title: "Bytes " + tinstance + " (TX)", total: true, color: "00ff00" }; + opts[rx] = { weight: 1, title: "Bytes " + tinstance + " (RX)", total: true, flip: true, color: "0000ff" }; + + rv.push({ + title: "%%H: OpenVPN Server \"%s\" - User Traffic - ".format(inst) + tinstance, + vlabel: "Bytes/s", + data: { + instances: { + if_octets: [ tinstance ] + }, + sources: { + if_octets: [ "tx", "rx" ] + }, + options: opts + } + }); + } + } - { + if (types.indexOf('users') > -1) { + let optionUsers = `users_${plugin_instance}`; + let optsUsers = {}; + optsUsers[optionUsers] = { title: "Total users connected", color: "00ff00" }; + let userInstances = graph.dataInstances(host, plugin, plugin_instance, 'users'); + if (userInstances.length > 0) { + rv.push({ + title: `%H: OpenVPN Server "${inst}" - Connected Users`, + vlabel: "Users", + y_min: "0", + alt_autoscale_max: true, + number_format: "%3.0lf", + data: { + instances: { + users: userInstances + }, + options: optsUsers + } + }); + } else { + console.error('Source "value" not found in any user instances:', sources); + } + } + + if (types.indexOf('compression') > -1) { + rv.push({ title: "%%H: OpenVPN \"%s\" - Compression".format(inst), vlabel: "Bytes/s", data: { @@ -46,7 +105,8 @@ return baseclass.extend({ compression_data_in_uncompressed : { weight: 3, title: "Uncompressed (RX)", total: true, flip: true, color: "0000ff" } } } - } - ]; + }); + } + return rv; } }); -- 2.30.2